package br.com.lucasddaniel.merchanmobile;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Environment;
import br.com.lucasddaniel.merchanmobile.bean.Device;
import br.com.lucasddaniel.merchanmobile.bean.DeviceAdapter;
import br.com.lucasddaniel.merchanmobile.bean.PacoteArquivoBean;
import br.com.lucasddaniel.merchanmobile.bean.PasseioBean;
import br.com.lucasddaniel.merchanmobile.bean.ResponsavelBean;
import br.com.lucasddaniel.merchanmobile.bean.TuristaBean;
import br.com.lucasddaniel.merchanmobile.dao.DispositivosBTRepositorio;
import br.com.lucasddaniel.merchanmobile.dao.ExcessaoBanco;
import br.com.lucasddaniel.merchanmobile.dao.PasseioRepositorio;
import br.com.lucasddaniel.merchanmobile.dao.ResponsavelRepositorio;
import br.com.lucasddaniel.merchanmobile.dao.TuristaAdaptadorBanco;
import br.com.lucasddaniel.merchanmobile.dao.TuristaRepositorio;
import br.com.lucasddaniel.merchanmobile.util.ArquivoRepositorio;

/**
 * Controlador principal de acesso aos dados.
 * 
 * @author ldsm
 * 
 */
public class Controller {

    private static Controller controller;
    private TuristaRepositorio turistaRepositorio;
    private ResponsavelRepositorio responsavelRepositorio;
    private PasseioRepositorio passeioRepositorio;
    private ArquivoRepositorio arquivoRepositorio;
    private DispositivosBTRepositorio dispositivosBTRepositorio;
    private ResponsavelBean responsavelLogado;
    private Context context;

    private Controller() {
        this.turistaRepositorio = new TuristaRepositorio();
        this.dispositivosBTRepositorio = new DispositivosBTRepositorio();
        this.arquivoRepositorio = new ArquivoRepositorio();
        this.passeioRepositorio = new PasseioRepositorio();
        this.responsavelRepositorio = new ResponsavelRepositorio();
    }

    /**
     * Cria uma instancia singletown do controlador.
     * 
     * @return
     */
    public static Controller getInstance() {
        if (controller == null) {
            controller = new Controller();
        }
        return controller;
    }

    /**
     * Insere um turista na base.
     * 
     * @param turista
     * @throws ExcessaoBanco
     */
    public void insereTurista(TuristaBean turista, Context ctx) throws ExcessaoBanco {
        turistaRepositorio.inserir(turista, ctx);
    }

    /**
     * Insere um responsavel na base.
     * 
     * @param ResponsavelBean
     * @throws ExcessaoBanco
     */
    public void insereResponsavel(ResponsavelBean resp, Context ctx) throws ExcessaoBanco {
        responsavelRepositorio.inserir(resp, ctx);
    }

    /**
     * Consulta um responsavel na base por login e senha.
     * 
     * @param ResponsavelBean
     * @throws ExcessaoBanco
     */
    public ResponsavelBean buscarResponsavel(ResponsavelBean resp, Context ctx) throws ExcessaoBanco {
        return responsavelRepositorio.buscar(resp, ctx);
    }

    /**
     * Atualiza um turista na base.
     * 
     * @param turista
     * @throws ExcessaoBanco
     */
    public void atualizaTurista(TuristaBean turista, Context ctx) throws ExcessaoBanco {
        turistaRepositorio.atualizar(turista, ctx);
    }

    /**
     * Lista todos os turistas.
     * 
     * @return
     * @throws ExcessaoBanco
     */
    public ArrayList<TuristaBean> listaTuristas(Context ctx) throws ExcessaoBanco {
        return turistaRepositorio.listar(ctx);
    }

    /**
     * Lista todos os passeios vendidos.
     * 
     * @return
     * @throws ExcessaoBanco
     */
    public List<PasseioBean> listaPasseios(Context ctx) throws ExcessaoBanco {
        return passeioRepositorio.listar(ctx);
    }

    /**
     * Consulta um turista pesquisando pelo nome ou codigo.
     * 
     * @param TuristaBean
     * @return
     * @throws ExcessaoBanco
     */
    public TuristaBean buscarTurista(TuristaBean t, Context ctx) throws ExcessaoBanco {
        return turistaRepositorio.buscar(t, ctx);
    }

    /**
     * Insere um passeio na base.
     * 
     * @param passeio
     * @throws ExcessaoBanco
     */
    public Integer inserePasseio(PasseioBean passeio, Context ctx) throws ExcessaoBanco {
        return passeioRepositorio.inserir(passeio, ctx);
    }

    /**
     * Atualiza um passeio na base.
     * 
     * @param passeio
     * @throws ExcessaoBanco
     */
    public void atualizarPasseio(PasseioBean passeio, Context ctx) throws ExcessaoBanco {
        passeioRepositorio.atualizar(passeio, ctx);
    }

    /**
     * Lista todos os pacotes do pacotes.txt do sdcard.
     * 
     * @return ArrayList<PacoteArquivoBean>
     * @throws ExcessaoBanco
     * @throws IOException
     * @throws FileNotFoundException
     */
    public List<PacoteArquivoBean> listarPacotesArquivo() throws ExcessaoBanco, FileNotFoundException, IOException {
        return passeioRepositorio.listarPacotesArquivo();
    }

    public List<PacoteArquivoBean> buscarPacotes(PasseioBean passeio, Context ctx) throws ExcessaoBanco {
        return passeioRepositorio.buscarPacotes(passeio, ctx);
    }

    /**
     * Exporta da base para um arquivo chamado atualizados.txt que será criado no diretorio do
     * sdcard /merchanmobile/
     * 
     * @param activity
     * @throws ExcessaoBanco
     * @throws FileNotFoundException
     * @throws IOException
     */
    public String exportarDados(Context ctx) throws ExcessaoBanco, FileNotFoundException, IOException {
        Calendar c = Calendar.getInstance();
        File file =
                new File(Environment.getExternalStorageDirectory() + "/merchanmobile/atualizados_" + c.get(Calendar.DAY_OF_MONTH) + "-" + (c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.YEAR) + "_"
                        + c.get(Calendar.HOUR_OF_DAY) + "-" + c.get(Calendar.MINUTE) + ".txt");
        file.createNewFile();
        FileOutputStream out = new FileOutputStream(file);

        arquivoRepositorio.exportarDados(out, ctx);
        return file.getName();
    }

    /**
     * Importa do arquivo turistas.txt que deve se encontrar no sdcard /merchanmobile/ para a base todos
     * os registros. Gerando assim um indice a cada registro cadastrado.
     * 
     * @return true se o arquivo de importação existir, senao false.
     * @param activity
     * @throws ExcessaoBanco
     * @throws FileNotFoundException
     * @throws IOException
     */
    public boolean importarDados(Context ctx) throws ExcessaoBanco, FileNotFoundException, IOException {
        return arquivoRepositorio.importarDados(ctx);
    }

    /**
     * Inicializa o adapter de acordo com a activity.
     * 
     * @param activity
     * @throws ExcessaoBanco
     */
    public void init2(Activity activity) throws ExcessaoBanco {
        this.context = activity.getApplicationContext();
        if (!TuristaAdaptadorBanco.estaAberto()) {
            TuristaAdaptadorBanco.abre(this.context);
        }
    }

    /**
     * Deleta todos os devices encontrados pela ultima vez ao procurar novos dispositivos
     * bluetooth.
     * 
     * @throws ExcessaoBanco
     */
    public void deletarDevices(Context ctx) throws ExcessaoBanco {
        dispositivosBTRepositorio.deletarDevices(ctx);
    }

    /**
     * Lista todos os dispositivos da base encontrados e cadastrados pela ultima vez pelo
     * bluetooth.
     * 
     * @param mAdapter
     * @return
     * @throws ExcessaoBanco
     */
    public DeviceAdapter listarDevices(DeviceAdapter mAdapter, Context ctx) throws ExcessaoBanco {
        return dispositivosBTRepositorio.listarDevices(mAdapter, ctx);
    }

    /**
     * Retorna o device Bluetooth marcado como principal.
     * 
     * @return Um Device
     * @throws ExcessaoBanco
     */
    public Device buscarDevicePrincipal(Context ctx) throws ExcessaoBanco {
        return dispositivosBTRepositorio.buscarDevicePrincipal(ctx);
    }

    /**
     * Cadastra uma lista de dispositivos encontrados pelo bluetooth.
     * 
     * @param mAdapter
     * @throws ExcessaoBanco
     */
    public void inserirTodosDevices(DeviceAdapter mAdapter, Context ctx) throws ExcessaoBanco {
        dispositivosBTRepositorio.inserirTodosDevices(mAdapter, ctx);
    }

    /**
     * Atualiza um dispositivo encontrados pelo bluetooth.
     * 
     * @param mDevice
     * @throws ExcessaoBanco
     */
    public void atualizarDevice(Device mDevice, Context ctx) throws ExcessaoBanco {
        dispositivosBTRepositorio.atualizar(mDevice, ctx);
    }

    public ResponsavelBean getResponsavelLogado() {
        return responsavelLogado;
    }

    public void setResponsavelLogado(ResponsavelBean responsavelLogado) {
        this.responsavelLogado = responsavelLogado;
    }
}
